﻿using Microsoft.EntityFrameworkCore;
using SJ.Platform.Common;
using SJ.Platform.EFCore.Model;
using SJ.Platform.EFCore.Model.ProjectManager;
using SJ.Platform.Extend.ModelExtend;
using SJ.Platform.Extend.ModelExtend.ProjectExt;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace SJ.Platform.EFCore.DBOperation.DBOperation.MySQL.Project
{
    public class Project_Requirement_InfoHandle
    {
        private readonly SJDBContext _context;

        public Project_Requirement_InfoHandle(SJDBContext context)
        {
            _context = context;
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<bool> CreateAsync(ProjectRequirementInfo entity)
        {
            try
            {
                _context.ProjectRequirementInfos.Add(entity);
                await _context.SaveChangesAsync();
                return true;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Requirement_InfoHandle=>Create", ex);
                return false;
            }
        }

        /// <summary>
        /// 批量新增
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<bool> BatchCreateAsync(List<ProjectRequirementInfo> list)
        {
            try
            {
                int result = 0;
                if (list != null && list.Count > 0)
                {
                    foreach (ProjectRequirementInfo entity in list)
                    {
                        _context.ProjectRequirementInfos.Add(entity);
                    }
                    result = await _context.SaveChangesAsync();
                }

                return result == list.Count;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Requirement_FeatureHandle=>BatchCreateAsync", ex);
                return false;
            }
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<bool> UpdateAsync(ProjectRequirementInfo entity)
        {
            try
            {
                _context.Entry(entity).State = EntityState.Modified;
                await _context.SaveChangesAsync();
                return true;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Requirement_InfoHandle=>Update", ex);
                return false;
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool Delete(ProjectRequirementInfo entity)
        {
            try
            {
                _context.ProjectRequirementInfos.Remove(entity);
                return _context.SaveChanges() > 0;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Requirement_InfoHandle=>Delete", ex);
                return false;
            }
        }

        /// <summary>
        /// 根据主键删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<bool> DeleteByIdAsync(string id)
        {
            try
            {
                var entity = _context.ProjectRequirementInfos.Find(id);
                if (entity != null)
                {
                    _context.ProjectRequirementInfos.Remove(entity);
                    await _context.SaveChangesAsync();
                    return true;
                }
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Requirement_InfoHandle=>DeleteById", ex);
            }
            return false;
        }

        /// <summary>
        /// 根据父级id删除
        /// </summary>
        /// <param name="pId"></param>
        /// <returns></returns>
        public async Task<bool> DeleteByPIdAsync(string pId)
        {
            try
            {
                var infos = await _context.ProjectRequirementInfos.Where(info => info.PId == pId).ToListAsync();
                int count = _context.Database.ExecuteSqlRaw($"delete from project_requirement_info where Pid='{pId}';");
                return infos.Count == count;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Requirement_InfoHandle=>DeleteByPIdAsync", ex);
            }
            return false;
        }

        /// <summary>
        /// 根据项目id删除
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public async Task<bool> DeleteByProjectIdAsync(string projectId)
        {
            try
            {
                var infos = await _context.ProjectRequirementInfos.AsNoTracking().Where(info => info.ProjectId == projectId).ToListAsync();
                int count = _context.Database.ExecuteSqlRaw($"delete from project_requirement_info where ProjectId='{projectId}';");
                return infos.Count == count;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Requirement_InfoHandle=>DeleteByProjectIdAsync", ex);
            }
            return false;
        }

        /// <summary>
        /// 根据ID获取实体
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ProjectRequirementInfo> GetEntityByIdAsync(string id)
        {
            try
            {
                return await _context.ProjectRequirementInfos.FindAsync(id);
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Requirement_InfoHandle=>GetEntityById", ex);
            }
            return null;
        }

        /// <summary>
        /// 根据ID获取实体
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ProjectRequirementInfoExtend> GetEntityExtByIdAsync(string id)
        {
            try
            {
                var entity = await _context.ProjectRequirementInfos.FindAsync(id);
                return entity.MapToExt<ProjectRequirementInfo, ProjectRequirementInfoExtend>();
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Requirement_InfoHandle=>GetEntityById", ex);
            }
            return null;
        }

        /// <summary>
        /// 根据需求ID获取需求详情
        /// </summary>
        /// <param name="requirementId"></param>
        /// <returns></returns>
        public async Task<List<ProjectRequirementInfoExtend>> GetRequirementsAndFeaturesByRequirementIdAsync(string requirementId)
        {
            try
            {
                string query = @"WITH RECURSIVE requirements AS (    
                                    SELECT *
                                    FROM project_requirement_info
                                    WHERE Id = '{0}'  

                                    UNION ALL    

                                    SELECT c.*
                                    FROM project_requirement_info c
                                    INNER JOIN requirements rc ON c.PId = rc.Id
                                )
                                SELECT * FROM requirements  ORDER BY sort;
                                ";
                query = string.Format(query, requirementId);
                List<ProjectRequirementInfo> requirements = await _context.ProjectRequirementInfos.FromSqlRaw(query).ToListAsync();
                List<ProjectRequirementInfoExtend> requirementExtends = requirements.MapToList<ProjectRequirementInfo, ProjectRequirementInfoExtend>();

                //需求下的功能
                if (requirementExtends != null && requirementExtends.Count > 0)
                {
                    foreach (var requirement in requirementExtends)
                    {
                        List<ProjectRequirementFeature> features = await _context.ProjectRequirementFeatures.Where(f => f.RId == requirement.Id).OrderBy(o => o.Sort).ToListAsync();
                        if (features != null && features.Count > 0)
                        {
                            requirement.ChildFeatures = new List<ProjectRequirementFeatureExtend>();
                            requirement.ChildFeatures = features.MapToList<ProjectRequirementFeature, ProjectRequirementFeatureExtend>();
                        }
                    }
                }

                return requirementExtends;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Requirement_InfoHandle=>GetRequirementsAndFeaturesByRequirementIdAsync", ex);
                return null;
            }
        }
        /// <summary>
        /// 获取子需求及其功能
        /// </summary>
        /// <param name="pExt"></param>
        /// <param name="requirementExt"></param>
        /// <returns></returns>
        private async Task GetChildRequirementsByPId(List<ProjectRequirementInfoExtend> infoExtList, ProjectRequirementInfoExtend requirementExt)
        {
            try
            {
                List<ProjectRequirementInfo> infos = await _context.ProjectRequirementInfos.Where(info => info.PId == requirementExt.Id).OrderBy(info => info.Sort).ToListAsync();
                if (infos != null && infos.Count > 0)
                {
                    List<ProjectRequirementInfoExtend> requirements = infos.MapToList<ProjectRequirementInfo, ProjectRequirementInfoExtend>();

                    foreach (var info in requirements)
                    {
                        List<ProjectRequirementFeature> features = await _context.ProjectRequirementFeatures.Where(f => f.RId == info.Id).OrderBy(f => f.Sort).ToListAsync();
                        if (features != null && features.Count > 0)
                        {
                            if (info.ChildFeatures == null)
                            {
                                info.ChildFeatures = new List<ProjectRequirementFeatureExtend>();
                            }
                            info.ChildFeatures = features.MapToList<ProjectRequirementFeature, ProjectRequirementFeatureExtend>();
                        }
                        infoExtList.Add(info);
                        GetChildRequirementsByPId(infoExtList, info);
                    }
                }
            }
            catch(Exception ex)
            {
                LogManager.WriteError("Project_Requirement_InfoHandle=>GetChildRequirementsByPId", ex);
            }
        }

        /// <summary>
        /// 根据项目ID获取需求及需求下的功能
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public async Task<List<ProjectRequirementInfoExtend>> GetRequirementsAndFeaturesByProjectIdAsync(string projectId)
        {
            try
            {
                //需求
                List<ProjectRequirementInfo> infos = await _context.ProjectRequirementInfos.Where(info => info.ProjectId == projectId).OrderBy(info => info.Sort).ToListAsync();
                List<ProjectRequirementInfoExtend> requirements = infos.MapToList<ProjectRequirementInfo, ProjectRequirementInfoExtend>();

                //需求下的功能
                if (requirements != null && requirements.Count > 0)
                {
                    foreach (var requirement in requirements)
                    {
                        List<ProjectRequirementFeature> features = await _context.ProjectRequirementFeatures.Where(f => f.RId == requirement.Id).OrderBy(f => f.Sort).ToListAsync();
                        if (features != null && features.Count > 0)
                        {
                            if (requirement.ChildFeatures == null)
                            {
                                requirement.ChildFeatures = new List<ProjectRequirementFeatureExtend>();
                            }
                            requirement.ChildFeatures = features.MapToList<ProjectRequirementFeature, ProjectRequirementFeatureExtend>();
                        }
                    }
                }

                return requirements;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Requirement_InfoHandle=>GetRequirementsByProjectId", ex);
                return null;
            }
        }

        /// <summary>
        /// 根据项目ID获取需求树
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public async Task<List<ProjectRequirementInfoExtend>> GetRequirementsByProjectIdAsync(string projectId)
        {
            try
            {
                //需求
                List<ProjectRequirementInfo> infos = await _context.ProjectRequirementInfos.Where(info => info.ProjectId == projectId).OrderBy(info => info.Sort).ToListAsync();
                //功能
                List<ProjectRequirementFeature> features = await _context.ProjectRequirementFeatures.Where(f => f.ProjectId == projectId).OrderBy(f => f.Sort).ToListAsync();

                List<ProjectRequirementInfoExtend> infoExtends = infos.MapToList<ProjectRequirementInfo, ProjectRequirementInfoExtend>();
                List<ProjectRequirementFeatureExtend> featureExtends = features.MapToList<ProjectRequirementFeature, ProjectRequirementFeatureExtend>();
                List<ProjectRequirementInfoExtend> extends = infoExtends.Where(info => string.IsNullOrWhiteSpace(info.PId)).ToList();
                BuildLevel(extends, infoExtends, featureExtends);
                return extends;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Requirement_InfoHandle=>GetRequirementsByProjectId", ex);
                return null;
            }
        }

        /// <summary>
        /// 生成需求层级树
        /// </summary>
        /// <param name="extends"></param>
        /// <param name="infoSource"></param>
        /// <param name="featureSource"></param>
        private void BuildLevel(List<ProjectRequirementInfoExtend> extends, List<ProjectRequirementInfoExtend> infoSource, List<ProjectRequirementFeatureExtend> featureSource)
        {
            foreach (var item in extends)
            {
                //功能层级
                var features = featureSource.Where(f => f.RId == item.Id && string.IsNullOrWhiteSpace(f.PId));
                if (features != null && features.Count() > 0)
                {
                    if (item.ChildFeatures == null)
                    {
                        item.ChildFeatures = new List<ProjectRequirementFeatureExtend>();
                    }
                    item.ChildFeatures = features.ToList();
                    BuildFeatureLevel(item.ChildFeatures, featureSource);
                }

                //需求层级
                var child = infoSource.Where(info => info.PId == item.Id);
                if (child != null && child.Count() > 0)
                {
                    if (item.ChildRequirementInfos == null)
                    {
                        item.ChildRequirementInfos = new List<ProjectRequirementInfoExtend>();
                    }

                    item.ChildRequirementInfos = child.ToList();
                    BuildLevel(item.ChildRequirementInfos, infoSource, featureSource);
                }
            }
        }
        /// <summary>
        /// 生成功能层级
        /// </summary>
        /// <param name="fe"></param>
        /// <param name="featureSource"></param>
        private void BuildFeatureLevel(List<ProjectRequirementFeatureExtend> fe, List<ProjectRequirementFeatureExtend> featureSource)
        {
            foreach (var item in fe)
            {
                var child = featureSource.Where(c => c.PId == item.Id);
                if (child != null && child.Count() > 0)
                {
                    if (item.ChildFeatures == null)
                    {
                        item.ChildFeatures = new List<ProjectRequirementFeatureExtend>();
                    }
                    item.ChildFeatures = child.ToList();
                    BuildFeatureLevel(item.ChildFeatures, featureSource);
                }
            }
        }
    }
}
